<script setup>
import { watch,ref,onMounted } from "vue"
import {saveClientConfig, getClientConfig, delClientConfig} from "@/store/ConfigStore.js"
import {saveClient, getClient, delClient} from "@/store/ClientStore.js"
import { UploadFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { data } from "autoprefixer"
import _ from "lodash"

// 定义本地消息状态类型
const TransportMsgType = {
  self:-1,
  text:0,
  file:1,
}

// 定义传输消息列表
const transportMessageList = ref([])

// 定义个性化设置的配置
const clientConfig = ref({
  autoDown:true,
  autoCopyText:false,
  autoReleaseConnection:true
})


// WebSocket 实例
let ws = null;

// webrpc配置
const rpcConfig = {
  iceServers: [], // 使用局域网环境时可能不需要 STUN/TURN
  iceTransportPolicy: 'all'
};

// 用户状态
const userName = ref('');
const clientList = ref([]);
const loggedIn = ref(false);
// const chatMessages = ref([]);

// 当前登录的用户
const user = ref({
  name:null,
  key:null
})

// 声明连接的client
const client = ref('')

// 多个连接的RTCPeerConnection对象
const peerConnectionList = ref(new Map())
const dataChannelList = ref(new Map())

// 发送的文件
// const file = ref(null)
const receivedFile = ref(null);

// 发送的文件进度
const sendFileProgress = ref(0)
// 发送的文件大小
const sendFileSize = ref(0)
// 正在发送的文件
const sendFileName = ref("")

// 聊天的文本输入框
const chatInput = ref('')

// 声明客户端连接权重数量
const clientConnectWeight = ref(new Map())
// 默认权重的初始值
const clientConnectWeightCount = 5

// dataChannel连接配置
const dataChannelDict = {
  "ordered":true,
  "maxRetransmits":30
}

// 连接超时时间，单位毫秒
const connectionTimeoutPeriod = 3000

// MessageType 静态变量
const MessageType = {
  login: 0,
  signal: 1,
  text: 2,
  user: 3,
  heartbeat : 4
};

const HeartbeatType = {
  ping:"ping",
  pong:"pong"
}


// 最大重连次数,5次
const maxRetryCount = 5
// 重连次数
let retryCount = 0

// 连接到 WebSocket 服务端
const connectWebSocket = () => {
  // 判断当前环境是否为发布环境
  
  // let wsUrl = 'ws://192.168.51.13:8900'
  let wsUrl = 'ws://localhost:8900'
  if(process.env.NODE_ENV === 'production'){
    // 正式发布版本，自适应域名，端口复用
    let url = window.location.host
    // 提供一个默认的url，用于cdn加速使用
    if (window.location.host.includes("cdn") || window.location.host.includes("files")){
      url = "file.suxii.cn"
    }
    wsUrl = `${window.location.protocol === 'https:' ? 'wss://' : 'ws://'}${url}`
  }

  ws = new WebSocket(wsUrl)
  ws.onopen = () => {
    console.log('WebSocket 连接成功')
    // 重置重连次数
    retryCount = 0
    // 连接成功，开始自动化登录
    getLoginClient()
    // 开启心跳
    handleHeartMessage()
    
  };

  ws.onmessage = (event) => {
    const message = JSON.parse(event.data);
    handleMessage(message);
  };

  ws.onclose = () => {
    // 关闭之后，立马清理定时器
    if(pingInterval != null){
       clearInterval(pingInterval)
       pingInterval = null
    }

    console.log("retryCount",retryCount,maxRetryCount)
    if(retryCount >= maxRetryCount){
      ws = null
      loggedIn.value = false
      user.value = null
      clientList.value = []
      console.log('WebSocket 连接关闭')
      ElMessage.error("连接已断开！")
      return
    }
    
    // 断线尝试重连
    console.log('WebSocket 连接关闭,尝试重新连接')
    retryCount+=1 
    connectWebSocket()
  };
};

var pingInterval
const handleHeartMessage = ()=>{
  // 每30秒发送一次ping消息
  pingInterval = setInterval(() => {
    if (ws != null && ws.readyState === WebSocket.OPEN) {
      // 发送心跳包
      ws.send(JSON.stringify({
            msgtype: MessageType.heartbeat,
            type: HeartbeatType.ping
          }));
    } else {
      clearInterval(pingInterval); // 连接关闭时清除定时器
    }
  }, 30000);  // 10000 毫秒 = 10 秒
}

// 处理接收到的消息
const handleMessage = (message) => {
  switch (message.msgtype) {
    case MessageType.login:
      handlerLogin(message);
      break;
    case MessageType.text:
      console.log('收到文本消息:', message.data);
      break;
    case MessageType.user:
      handlerUser(message)
      break;
    case MessageType.signal:
      handleSignalMessage(message);
      break;
    default:
      console.log('未知消息类型');
  }
};

// 处理更新用户
const handlerUser =(message)=>{
  clientList.value = message.data.filter(c=>c.key != user.value.key)
  console.log('更新的用户列表:', clientList.value)

  // 更新权重
  if (clientConfig.value.autoReleaseConnection) {
    // todo 暂时先不考虑，新增用户保留之前的权重
    clientConnectWeight.value.clear()
    clientList.value.forEach(client => {
      clientConnectWeight.value.set(client.key, clientConnectWeightCount)
    })
  }


  // 移除已经离线的用户
  const keys = clientList.value.map(e=>e.key)
  dataChannelList.value.forEach((dataChannel,key)=>{
    if(!keys.includes(key)){
      console.log("移除了已经离线的客户端",key)
      dataChannel = null
      dataChannelList.value.delete(key)
    }
  })

  // 重置文件发送 
  // 如果当前key失效，说明这个客户端已经离线了，那么与这个客户端的文件传输应该终止
  if(!isRightKey()){
    sendFileProgress.value = 0
    sendFileSize.value = 0
  }
}

// 处理登录成功信息
const handlerLogin=(message)=>{
  user.value.name = message.name
  user.value.key = message.key
  console.log('登录的用户信息:', user.value)
}

// 处理信令消息
const handleSignalMessage = async (message) => {
  if (message.type === 'offer') {
    await handleOffer(message);
  } else if (message.type === 'answer') {
    await handleAnswer(message);
  } else if (message.type === 'candidate') {
    await handleCandidate(message);
  }
};

// 创建点对点连接
const createPeerConnection = () => {

  peerConnectionList.value.set(client.value, new RTCPeerConnection(rpcConfig));
  const peerConnection = peerConnectionList.value.get(client.value);

  // ICE 处理
  peerConnection.onicecandidate = (event) => {
    // todo 第一次连接，这里发送了五次
    console.log("ICE 处理", event.candidate);
    if (event.candidate) {
      ws.send(JSON.stringify({
        msgtype: MessageType.signal,
        client: client.value,
        type: 'candidate',
        data: event.candidate
      }));
    }
  };

  // 监听远端 DataChannel 创建事件
  peerConnection.ondatachannel = (event) => {
    const receivedChannel = event.channel;
    console.log(`收到新的 DataChannel: ${receivedChannel.label}`);

    // 为不同的 DataChannel 分别设置消息处理
    receivedChannel.onmessage = (event) => {
      console.log(`收到来自 ${receivedChannel.label} 通道的消息:`, event.data);
      if (receivedChannel.label === 'chat') {
        chatDataChannelOnmessage(event)
      } else if (receivedChannel.label === 'file') {
        fileDataChannelOnmessage(event)
      }
    };

    receivedChannel.onopen = () => {
      console.log(`${receivedChannel.label} DataChannel 已打开`);
    };

    receivedChannel.onclose = () => {
      console.log(`${receivedChannel.label} DataChannel 已关闭`);
    };
  };

  // todo 这里后期也可以自定义，客户端可以选择是否开启哪些channel
  createChatPeerConnection(peerConnection)
  createFilePeerConnection(peerConnection)
};

const chatDataChannelOnmessage = (event) => {
  console.log("chatDataChannelOnmessage", event.data);

  const data = JSON.parse(event.data)
  transportMessageList.value.push({
    name:data.name,
    type:TransportMsgType.text,
    data:data.data
  })
  /* chatMessages.value.push({
    from: `对方(${client.value})`,
    data: event.data
  }); */
}

// 接收的文件名
const receivedFileName = ref("");
// 接收的文件大小
const recivedFileSize = ref(0)
// 正在接收的文件大小
const recivingFileSize = ref(0)
// 发送方的key
const recivedClient = ref('')
let receivedFileChunks = ref([]); // 用于存储接收到的文件数据
const fileDataChannelOnmessage = (event) => {
  console.log("fileDataChannelOnmessage: ", event.data);
  if (typeof event.data === 'string') {
    const message = JSON.parse(event.data);
    if (message.type === 'fileInfo') {
      receivedFileChunks.value = []; // 清空数组以接收新的文件数据
      receivedFile.value = null; // 初始化接收文件对象
      receivedFileName.value = message.name; // 保存文件名
      recivedFileSize.value = message.size
      recivedClient.value = message.client

    } else if (message.type === 'end') {
      console.log('文件传输完成', receivedFileName.value);
      // 将文件数据转换为 Blob
      receivedFile.value = new Blob(receivedFileChunks.value, { type: 'application/octet-stream' });

      // 接收完成后设置为0
      // recivedFileSize.value = 0
      // recivingFileSize.value = 0
      // 处理接收的文件
      ElMessage({message: `已经接收文件${receivedFileName.value}）`,type: 'success'})
      transportMessageList.value.push({
        name: recivedClient.value, 
        type: TransportMsgType.file, 
        data: receivedFileName.value
      })
      downloadFile()

    }
  } else {
    // 接收二进制数据并存储到数组中
    receivedFileChunks.value.push(event.data);
    recivingFileSize.value = calculateReceivedFileSize()
  }
};

// 计算 receivedFileChunks 的大小
const calculateReceivedFileSize= ()=> {
  return receivedFileChunks.value.reduce((totalSize, chunk) => totalSize + chunk.byteLength, 0);
}


// 下载文件
const downloadFile = () => {
  if (!receivedFile.value) return;

  // 触发下载
  const downloadLink = document.createElement('a');
  downloadLink.href = URL.createObjectURL(receivedFile.value);
  downloadLink.download = receivedFileName.value;
  downloadLink.click();

  // 释放 URL 对象
  URL.revokeObjectURL(downloadLink.href);
};

const createChatPeerConnection = (peerConnection) => {
  console.log("createChatPeerConnection", client.value);

  // 创建 DataChannel
  const dataChannel = peerConnection.createDataChannel('chat',dataChannelDict);
  if (!dataChannelList.value.has(client.value)) {
    dataChannelList.value.set(client.value, {
      chat: null,
      file: null
    });
  }
  dataChannelList.value.get(client.value).chat = dataChannel
  dataChannel.onopen = () => {
    console.log('ChatDataChannel 已打开');
  };


}

// 检查key是否合理
const isRightKey = ()=>{
  return clientList.value.map(e=>e.key)
  .indexOf(client.value) !== -1
}

// 发送聊天信息
const sendChatMessage = async () => {

  if(client.value === '' || !isRightKey()){
    ElMessage.error("未选择发送的客户端")
    return
  }

  if(chatInput.value === ''){
    ElMessage.error("请输入内容")
    return
  }

  const text = chatInput.value
  chatInput.value = ''

  await sendOffer(client.value)

  if (!dataChannelList.value.has(client.value)) {
    console.error('ChatDataChannel 未打开或不可用')
    return
  }

  const dataChannel = dataChannelList.value.get(client.value).chat;
  console.log("message", dataChannelList.value);
  console.log("message", dataChannel);

  if (dataChannel && dataChannel.readyState === 'open') {
    dataChannel.send(JSON.stringify({
      name:user.value.name,
      data:text
    }));
    transportMessageList.value.push({
      name:"我",
      type:TransportMsgType.self,
      data:text
    })
  } else {
    console.error('ChatDataChannel 未打开或不可用');
  }
};

const createFilePeerConnection = (peerConnection) => {
  console.log("createFilePeerConnection", client.value);
  // 创建 DataChannel
  const dataChannel = peerConnection.createDataChannel('file',dataChannelDict);
  if (!dataChannelList.value.has(client.value)) {
    dataChannelList.value.set(client.value, {
      chat: null,
      file: null
    });
  }
  dataChannelList.value.get(client.value).file = dataChannel
  dataChannel.onopen = () => {
    console.log('FileDataChannel 已打开');
  };


}




// 发送offer
const sendOffer = async (clientKey) => {
  client.value = clientKey

  if (!peerConnectionList.value.has(client.value)) {
    createPeerConnection();
  }

  // 如果dataChannel列表已经有客户端，说明连接已经建立了
  if (dataChannelList.value.has(client.value)) {
    // 当文件channel状态为open说明已经建立连接了，直接返回
    const dataChannel = dataChannelList.value.get(client.value)
    const fileDataChannel = dataChannel.file
    if (fileDataChannel != null && fileDataChannel.readyState === "open") {
      console.log("sendOffer 已经建立连接");
      return
    }
  }

  console.log("发送offer");
  // 设置连接的用户
  const peerConnection = peerConnectionList.value.get(client.value);
  
  const offer = await peerConnection.createOffer();
  await peerConnection.setLocalDescription(offer);
  ws.send(JSON.stringify({
    msgtype: MessageType.signal,
    client: client.value,
    type: 'offer',
    data: offer
  }));

  // 一直阻塞，知道连接建立之后再返回
  let time = 0;
  await new Promise((resolve,reject) => {
    const intervalId = setInterval(() => {
      time += 100;
      if(time >= connectionTimeoutPeriod){
        const name = clientList.value.find(e=> e.key === client.value).name
        transportMessageList.value.push({
          name:"系统消息",
          type:TransportMsgType.text,
          data:`与客户端 ${name} 建立连接失败`
      })
        clearInterval(intervalId);
        reject(new Error("连接失败")); // 拒绝 Promise 并抛出异常
        return;
      }

      const dataChannel =dataChannelList.value.get(client.value)
      const fileDataChannel = dataChannel.file
      
      if (fileDataChannel!=null && fileDataChannel.readyState === "open") {
        console.log("dataChannel",dataChannel);
        clearInterval(intervalId);
        resolve();
      }
    }, 100); // 每 100 毫秒检查一次
  });
  console.log("DataChannel 建立完成");

}

// 处理 offer
const handleOffer = async (message) => {
  console.log("处理offer", message)
  client.value = message.client

  if (!peerConnectionList.value.has(message.client)) {
    createPeerConnection();
  }

  console.log("handleOffer", peerConnectionList.value);

  const peerConnection = peerConnectionList.value.get(message.client);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(message.data));

  const answer = await peerConnection.createAnswer();
  await peerConnection.setLocalDescription(answer);

  ws.send(JSON.stringify({
    msgtype: MessageType.signal,
    client: message.client,
    type: 'answer',
    data: answer
  }));
};

// 处理 answer
const handleAnswer = async (message) => {
  const peerConnection = peerConnectionList.value.get(client.value);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(message.data));
};

// 处理 ICE candidate
const handleCandidate = async (message) => {
  try {
    const peerConnection = peerConnectionList.value.get(client.value);
    await peerConnection.addIceCandidate(new RTCIceCandidate(message.data));
  } catch (e) {
    console.error('添加 ICE Candidate 时出错:', e);
  }
};

// 登录
const login = () => {
  if (!userName.value) {
    alert('请输入用户名');
    return;
  }

  const loginMessage = {
    msgtype: MessageType.login,
    name: userName.value
  };

  if(ws == null){
    ElMessage.error("登录失败，连接已断开，请刷新页面重试！")
    return
  }

  ws.send(JSON.stringify(loginMessage));
  loggedIn.value = true;
  saveClient({name:userName.value})
};

// 退出登录
const logout = ()=>{
  delClient()
  ws.close(1000,"退出登录")
  ws = null
  loggedIn.value = false
  // 退出登录文件发送进度仍然在继续，好像不用修复，基于点对点连接的跟服务端没有关系，可以发送，暂时先不改了
}

// 获取登录用户信息
const getLoginClient =()=>{
  const loginClient = getClient()
  if(loginClient == null){
    return
  }
  userName.value = loginClient.name
  loggedIn.value = true
  login()

}

// 断开点对点连接的方法
const disconnect = () => {
  const dataChannel = dataChannelList.value.get(client.value);
  if (dataChannel && dataChannel.readyState === 'open') {
    console.log(client.value, '断开点对点连接');
    dataChannel.close();
    dataChannelList.value.delete(client.value);
  }

  const peerConnection = peerConnectionList.value.get(client.value);
  if (peerConnection) {
    peerConnection.close();
    peerConnectionList.value.delete(client.value);
    console.log(client.value, '释放 peerConnection');
  }

  // console.log("当前的连接peerConnection：", peerConnectionList.value);
  // console.log("当前的连接dataChannel：", dataChannelList.value);

}

// 切换客户端
const switchClient = (clientKey) => {
  client.value = clientKey
}

// 发送文件
const sendFile = async (key,file, sendSuccessCallback) => {
  if (!file) return;
  // 清空文件发送状态
  sendFileProgress.value = 0

  console.log("当前发送的文件是",file.name,"key",client.value)
  
  const dataChannel = dataChannelList.value.get(key).file;
  const chunkSize = 1024 * 64; // 增大 chunk 大小以提高速度
  const reader = new FileReader();

  reader.onload = async (event) => {
    const arrayBuffer = event.target.result;
    const chunks = [];

    // 设置要发送的文件大小
    sendFileSize.value = arrayBuffer.byteLength
    // 设置发送的文件名字
    sendFileName.value = file.name

    for (let i = 0; i < arrayBuffer.byteLength; i += chunkSize) {
      chunks.push(arrayBuffer.slice(i, i + chunkSize));
    }

    // 发送详细信息
    // dataChannel.send(JSON.stringify({ type: 'filename', value: file.value.name }));
    dataChannel.send(JSON.stringify({ 
      type:"fileInfo",
      name:file.name,
      size:file.size,
      client:user.value.name,// todo 等完成了服务端返回当前客户端再修改
     }));

    for (const chunk of chunks) {
      while (dataChannel.bufferedAmount >= chunkSize * 2) {
        // 仅在 buffer 过满时等待，减少不必要的延迟
        await new Promise((resolve) => setTimeout(resolve, 20));
      }
      dataChannel.send(chunk);
      // 设置发送的文件进度
      sendFileProgress.value += chunk.byteLength
    }

    dataChannel.send(JSON.stringify({ type: 'end' }));
    console.log('文件发送完成');
    ElMessage({message: `文件（${file.name}）发送成功`,type: 'success'})
    // 设置当前文件发送状态为完成
    // sendFileState.value = true
    // 文件发送成功接口回调
    sendSuccessCallback()
    // 设置文件发送进度为文件实际进度
    sendFileProgress.value = sendFileSize.value
    // 添加到发送传输记录列表
    transportMessageList.value.push({name:"我",type:TransportMsgType.self,data:file.name})
    handlerClientWeight()

  };

  reader.readAsArrayBuffer(file);
};


// 处理客户端权重
const handlerClientWeight = ()=>{
  // 配置没有开启就return
  if(!clientConfig.value.autoReleaseConnection) return

  // 所有的值权重-1
  clientConnectWeight.value.forEach((count,key)=>{
    clientConnectWeight.value.set(key,count-=1)
  })

  // 当前传输的client保存初始化
  clientConnectWeight.value.set(client.value,clientConnectWeightCount)

  // 处理要回收的客户端
  clientConnectWeight.value.forEach((count,key)=>{
    if(count<=0){
      // 先切换目标客户端
      switchClient(key)
      // 断开连接
      disconnect()
    }
  })
  

}


// 获取配置信息
const getConfig = ()=>{
  const config = getClientConfig()
  if(config != null){
    clientConfig.value = config
  }
}

// 更改配置信息
const changeConfig = ()=>{
  saveClientConfig(clientConfig.value)
}


// 处理文件选择
const handleFileChange = (f, fileList,client) => {
  debouncedFunSingle(fileList,client)
}


// 给全部在线客户端发送文件
const sendToAllClient = (f,fileList)=>{
  debouncedFunMore(fileList)

}

//处理文件通道有文件发送的情况
const handleFileChannelSend = ()=>{  
  if(sendFileProgress.value !== sendFileSize.value){
    ElMessage.warning("请等待列表文件发送完成")
    return false
  }
  return true
}

// 处理单个用户发送的文件列表
const handleSendFileList = async (singleSendFileList,client) => {
  if(!handleFileChannelSend()){
    return;
  }

  const list = singleSendFileList.map(e=>e.raw)

  console.log("handleSendFileList",list)
  await sendOffer(client.key)
  handleNextFile(client.key,list,0)
}

// 处理全部发送的文件列表
const handleAllClientSendFileList = async (singleSendFileList) => {
  if(!handleFileChannelSend()){
    return;
  }

  const list = singleSendFileList.map(e=>e.raw)

  for (var client of clientList.value) {
    // todo 这个地方总是第一个发送一个，其他全发给第二个了
    await sendOffer(client.key)
    handleNextFile(client.key,list,0)
  }
}

// 递归发送
const handleNextFile = (key,fileList,index)=>{
  if(index >= fileList.length) return

  sendFile(key,fileList[index],()=>{
    handleNextFile(key,fileList,index + 1)
  })  

}

const handleBeforeUpload=(file)=> {  
  // 阻止默认上传行为
  return false;
}




// 使用watch的深度监听
watch(()=> clientConfig,(newValue,oldValue)=>{
  // 目前先强制自动下载
  if (newValue.value.autoDown == false) {
    new Promise((resolve) => {
      const intervalId = setInterval(() => {
        clientConfig.value.autoDown = true
        clearInterval(intervalId);
        resolve();
      }, 300);
    });
  }
  changeConfig()
},{deep:true})

  // 文件选择去抖动
  const debouncedFunSingle = _.debounce(handleSendFileList,300)
  const debouncedFunMore = _.debounce(handleAllClientSendFileList,300)


onMounted(() => {
  console.log("当前环境为：",process.env.NODE_ENV)

  // 初始化个性化设置信息
  getConfig()
  // 连接信令服务器
  connectWebSocket()

  
/*   transportMessageList.value.push({name:"clientA",type:TransportMsgType.text,data:"hello"})
  transportMessageList.value.push({name:"clientB",type:TransportMsgType.file,data:"hello2.zip"})
  transportMessageList.value.push({name:"clientC",type:TransportMsgType.text,data:"hello3"})
  transportMessageList.value.push({name:"我",type:TransportMsgType.self,data:"a.txt"}) */

/*   clientList.value.push({name:"clientA",key:"clientA key"})
  clientList.value.push({name:"clientB",key:"clientB key"})
  clientList.value.push({name:"clientC",key:"clientC key"})
  clientList.value.push({name:"clientD",key:"clientD key"}) */
})

</script>

<template>
  <main class="xl:container xl:mx-auto h-screen bg-[#efefef]  flex justify-end py-10">
    <!-- 主布局 -->
    <div class="flex flex-col w-full mr-8">


      <div class="w-full h-full flex flex-col ">
        <!-- 登录布局 -->
        <div v-if="!loggedIn">
          <div class="w-full h-auto flex flex-row p-4 bg-white rounded-lg gap-4 justify-center">
            <el-input @keyup.enter="login" v-model="userName" style="width: 240px" placeholder="请输入用户名" clearable />
            <el-button type="primary" @click="login">登录</el-button>
          </div>
        </div>
        <!-- 中间在线的客户端 -->
        <div v-else>
          <div class="w-full flex flex-row justify-end">
            <el-button type="danger" @click="logout">退出登录</el-button>
          </div>
          <div class="w-full h-auto flex flex-wrap gap-y-4 gap-x-12 p-4">
            <!-- 底部文件上传框 -->
            <div class=" p-0 h-auto w-full ">
              <!-- <h1 class=" text-center w-full h-full">点击或者拖动文件到此处与全部在线客户端传输文件</h1> -->


              <el-upload  drag action="#" :before-upload="(_)=>false" multiple
                 :on-change="(file, fileList) => sendToAllClient(file, fileList)">
                <i class="el-icon-upload"></i>
                  <div class="el-upload__text">拖拽文件到这里，或<em>点击发送</em>给全部在线客户端</div>
              </el-upload>


            </div>

            <div class=" bg-blue-300 p-2 rounded-2xl w-60 h-40 flux flux-col shadow-md">
              <h1 class=" text-white font-bold text-2xl">我：{{ user.name }}</h1>
            </div>

            <!-- 单个客户端的布局 -->
            <div class="bg-white p-2 rounded-2xl w-60 h-40 flux flux-col shadow-md  font-bold"
              v-for="(item, index) in clientList" :key="index">

              <div>{{ item.name }}</div>
              <div class="relative w-full h-full">
                <el-upload class="upload-demo w-full absolute inset-0" drag action="#" multiple
                  :before-upload="handleBeforeUpload"
                  :on-change="(file, fileList) => handleFileChange(file, fileList, item)">
                  <i class="el-icon-upload"></i>
                  <div class="el-upload__text">拖拽文件到这里，或<em>点击发送</em></div>
                </el-upload>
              </div>

            </div>

          </div>
        </div>
      </div>

      <!-- 中间剩余部分 -->
      <div class="flex ">

      </div>
    </div>

    <!-- 右侧面板 -->
    <div class="flex flex-col gap-4 w-full max-w-xs ">
      <!-- 个性化设置 -->
      <div class="bg-white p-4 rounded-lg  shadow-md">
        <h3 class="text-lg font-semibold">个性化设置：</h3>
        <div class="mt-2">
          <label class="block">
            <el-switch v-model="clientConfig.autoDown" /> 自动下载传输文件
          </label>
          <label class="block mt-2">
            <el-switch v-model="clientConfig.autoCopyText" /> 自动复制文字消息
          </label>
          <label class="block mt-2">
            <el-switch v-model="clientConfig.autoReleaseConnection" /> 自动回收连接
          </label>
        </div>
      </div>

      <!-- 传输记录 -->
      <div class="flex flex-col w-full gap-2">
        <div class="bg-white p-2 rounded-md shadow-md">
          <h3 class="text-lg font-semibold italic text-center">传输记录</h3>
        </div>

        <!-- 发送文件的列表 -->
         <div  v-if="sendFileProgress != 0 || recivedFileSize != 0" class=" bg-white p-2 rounded-md shadow-md w-full flex flex-col justify-center">
          <div v-if="sendFileProgress != 0">
            <div class=" text-gray-400">发送的文件：</div>
                <el-progress :text-inside="true" :stroke-width="24"
                  :percentage="sendFileProgress/sendFileSize * 100">
                  ({{ (sendFileProgress/sendFileSize).toFixed(2) * 100 }}%){{ sendFileName }}
                </el-progress>
          </div>
          <div v-if="recivedFileSize != 0">
            <div class=" text-gray-400">接收的文件：</div>
                <el-progress :text-inside="true" :stroke-width="24"
                  :percentage="recivingFileSize/recivedFileSize * 100" status="success">
                  ({{ (recivingFileSize/recivedFileSize).toFixed(2) * 100 }}%){{ receivedFileName }}
                </el-progress>
          </div>
         </div>

        <!-- 接收文件的进度 -->
<!--         <el-progress v-if="recivedFileSize != 0" :text-inside="true" :stroke-width="24"
          :percentage="recivingFileSize/recivedFileSize * 100" status="success">
          ({{ (recivingFileSize/recivedFileSize).toFixed(2) * 100 }}%){{ receivedFileName }}
        </el-progress> -->

        <!-- 聊天框 -->
        <div class="bg-white p-2 rounded-md shadow-md">
          <div class="w-full h-full flex flex-row-reverse">
            <el-button type="primary" @click="sendChatMessage">发送</el-button>
            <div class="w-full h-full flex flex-row">
              <div>

                <el-select v-model="client" placeholder="Select">
                  <el-option v-for="item in clientList" :key="item.key" :label="item.name" :value="item.key" />
                </el-select>

              </div>
              <el-input @keyup.enter="sendChatMessage" v-model="chatInput" placeholder="请输入内容" />
            </div>
          </div>

        </div>

        <!-- 消息列表 -->
        <div class="bg-white rounded-lg shadow-md p-5">
          <div class="flex flex-col w-full gap-1" v-for="(item, index) in transportMessageList" :key="index">
            <div class=" flex flex-row gap-1">

              <div v-if="item.type != TransportMsgType.self" class="text-yellow-400">{{item.name}}:</div>
              <div v-else class="text-green-500">我:</div>

              <div v-if="item.type == TransportMsgType.text">{{ item.data }}</div>
              <div v-else="item.type == TransportMsgType.file">
                <div>发送了 <a href="#">{{item.data}}</a></div>
                <!-- <div class="no-underline hover:underline text-blue-600">{{item.data}}</div> -->
              </div>

            </div>
          </div>
          <div v-if="transportMessageList.length <= 0">暂无传输消息</div>
        </div>

      </div>
    </div>


  </main>
</template>



<style scoped></style>